#include "app_pool.h"

typedef struct
{
    int pool_size;      // 线程池大小
    pthread_t *threads; // 线程池的线程

    char *mq_name; // 队列名
    mqd_t mq;      // 队列描述符
} app_pool_t;
static app_pool_t pool;

typedef struct
{
    void (*task_fun)(void *); // 任务函数
    void *arg;                // 任务函数的参数
} app_pool_task_t;

void *thread_fun(void *);

gate_status_t app_pool_init(int pool_size)
{
    pool.pool_size = pool_size;
    pool.threads = (pthread_t *)malloc(sizeof(pthread_t) * pool_size);

    // 消息队列: 存储是任务要执行的函数
    pool.mq_name = "/pool";
    struct mq_attr attr;
    attr.mq_flags = 0;                         // 阻塞式读取消息
    attr.mq_maxmsg = 10;                       // 队列存储的最大消息数
    attr.mq_msgsize = sizeof(app_pool_task_t); // 队列中每条消息的最大字节数
    pool.mq = mq_open(pool.mq_name, O_CREAT | O_RDWR, 0666, &attr);
    if (pool.mq == (mqd_t)-1)
    {
        perror("消息队列创建失败");
        return GATE_ERROR;
    }
    log_info("消息队列创建成功");

    // 创建线程
    for (size_t i = 0; i < pool_size; i++)
    {
        int r = pthread_create(&pool.threads[i], NULL, thread_fun, NULL);
        if (r != 0)
        {
            perror("线程创建失败");
            return GATE_ERROR;
        }
    }

    log_info("线程池初始化成功");
    return GATE_OK;
}

void app_pool_deinit(void)
{
    // 停止线程
    for (size_t i = 0; i < pool.pool_size; i++)
    {
        pthread_cancel(pool.threads[i]);
    }
    free(pool.threads);
    pool.threads = NULL;

    mq_close(pool.mq);
    mq_unlink(pool.mq_name);
    pool.mq = (mqd_t)-1;
}

void *thread_fun(void *args)
{
    while (1)
    {
        app_pool_task_t task;
        ssize_t len = mq_receive(pool.mq, (char *)&task, sizeof(app_pool_task_t), NULL);
        if (len == sizeof(app_pool_task_t) && task.task_fun)
        {
            task.task_fun(task.arg);
        }
    }
}

gate_status_t app_pool_add_task(void (*task_fun)(void *), void *arg)
{
    if (task_fun == NULL)
    {
        log_error("任务添加失败: 任务函数不能为NULL");
        return GATE_ERROR;
    }

    app_pool_task_t task = {
        .task_fun = task_fun,
        .arg = arg};
    if (mq_send(pool.mq, (char *)&task, sizeof(app_pool_task_t), 0) == -1)
    {
        perror("任务添加失败");
        return GATE_ERROR;
    }
    // log_info("任务添加成功");
    return GATE_OK;
}
